The talk is about a Tcl/Tk application developed by the author for a big international radiocommunication company. A great part of the software being developed at that company uses the multi-platform GUI framework Qt, which has, among others, a good multi-platform support. The Tcl/Tk tool presented in the talk has proved invaluable for keeping the translations consistent and managing the translation process for a variety of European and Asian languages.
QChar
and QString
, support for encodings like
"Big5"
, "EUC-JP"
, "ISO-8859-1"
,
"UTF-8"
, "UTF-16"
, etc.).QLineEdit
and
QTextEdit
work well with any input method installed on the
system.tr()
static method, available in all classes derived
from QObject
:
// From within a class derived from QObject myButton->setText(tr("Press Me!"); writeToLog(tr("Cannot connect to host '%1'.").arg(hostName)); // From within a global function or a class not derived from QObject: myButton->setText(QObject::tr("Press Me!");
QObject
by setting all their translatable strings within a
dedicated method (often called retranslate()
or
retranslateUi()
) and invoking this method when handling an
event of the type QEvent::LanguageChange
or some dedicated
signal emitted whenever the user selects a different language.
ProjectName
making up the
application: Run the Qt command line tool lupdate
to
extract the translatable strings from the source project's source files as
well as its UI description (.ui
) files into translation
source files having names like ProjectName_de.ts
,
ProjectName_fr.ts
, etc.lrelease
to generate binary
Qt message .qm
files from the translated
.ts
files. It is common practice to convert several
.ts
files to one and the same .qm
file, placed
into the translations
subdirectory of the directory containing
the executable and its DLLs.qt_de.qm
,
qt_fr.qm
, etc.) bundled with the Qt distribution into the
translations
subdirectory mentioned above.QTranslator
class objects. Repeat this action for any of
the supported languages whenever the user selects another one.translations
subdirectory will be distributed and installed together with the
application.Fulfilling these requirements by using Qt Linguist only is nearly impossible. Typical middle-size software has about 10,000 texts to be translated, quite often contained in about 100 translation files, which in turn are to be processed by one or more translators for each language supported by the application(s).
The Tcl/Tk tool TransCheck, developed recently by the author for a big radiocommunication company, has proved to be of great help in mastering the above-mentioned requirements and managing the translation process.
bin
: files TransCheck.tcl
,
TransCheck_Manual.chm
.lib
: packages tablelist5.9
,
tooltip-1.4.4
, winhelp1.0
.
main.tcl
.
tablelist::tablelist $tbl \ -columns { 64 "Source Text" 64 "Translated Text" 0 "Project" 0 "Context" } \ -activestyle frame -background white -borderwidth 0 -showseparators yes \ -spacing 1 -width 200 -height 40 -movablecolumns yes -stretch all \ -labelcommand tablelist::sortByColumn \ -labelcommand2 tablelist::addToSortColumns \ -tooltipaddcommand tooltipAddCmd -tooltipdelcommand tooltipDelCmd \ -xscrollcommand [list $hsb set] -yscrollcommand [list $vsb set] if {$::tcl_platform(osVersion) < 6.0} { ;# Windows XP $tbl configure -stripebackground #e8e8e8 } else { ;# Windows Vista/7 $tbl configure -stripebackground #f6f6f6 }
$tbl columnconfigure 0 -name "srcText" -sortmode asciinocase -wrap yes $tbl columnconfigure 1 -name "trText" -sortmode asciinocase -wrap yes $tbl columnconfigure 2 -name "project" -sortmode asciinocase -maxwidth 32 \ -changesnipside yes $tbl columnconfigure 3 -name "context" -sortmode asciinocase -maxwidth 32 \ -changesnipside yes
proc tooltipAddCmd {tbl row col} { if {($row >= 0 && [$tbl iselemsnipped $row,$col fullText]) || ($row < 0 && [$tbl istitlesnipped $col fullText])} { tooltip::tooltip $tbl $fullText } } proc tooltipDelCmd tbl { tooltip::tooltip $tbl "" }
set rowCount [$tbl size] for {set row 0} {$row < $rowCount} {incr row} { $tbl rowconfigure $row -hide 1 } set searchCmd [list $tbl searchcolumn $col $pattern -all -glob] if {!$caseSens} { lappend searchCmd -nocase } . . . set rowList [eval $searchCmd] foreach row $rowList { $tbl rowconfigure $row -hide 0 }